package com.hightrast.service.component;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hightrast.service.api.baseEntity.exception.ServiceException;
import com.hightrast.service.api.constant.SystemConstant;
import com.hightrast.service.api.entity.RastUser;
import com.hightrast.service.api.redis.RedisConstant;
import com.hightrast.service.redis.RedisService;
import com.hightrast.service.service.IRastUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.nio.charset.StandardCharsets;
import java.util.Random;
import java.util.concurrent.TimeUnit;

// 加入Spring容器
@Component
@Slf4j
public class MailClient {

    @Resource
    private JavaMailSender mailSender;// 引入mail依赖后即可注入该类，通过该类实现邮件发送的最终方法。

    @Value("${spring.mail.username}")
    private String from;//定义发件人 ，从配置文件中读取

    @Resource
    RedisTemplate<String, Object> redisService;

    @Resource
    IRastUserService userService;

    /**
     * 发送邮件功能
     *
     * @param to                       收件人邮箱，随意，可以是@163.com，也可以是@qq.com
     * @param theme，主题，当前邮件主题
     * @param content，邮件内容非管理员不能获取用户列表 发送邮件失败会保存日志
     */
    public void sendMail(String to, String theme, String content) {
        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(theme);
            helper.setText(content, true);//不加参数默认是文本，加上true之后支持html格式文件
            mailSender.send(helper.getMimeMessage());
        } catch (MessagingException e) {
            log.error("发送邮件失败:" + e.getMessage());
        }
    }

    /**
     * 发送邮件功能
     *
     * @param to   收件人邮箱，随意，可以是@gmail.com，也可以是@qq.com
     *             发送邮件失败会保存日志
     * @param way  发送方式
     * @param page 页面
     */
    public void senMailVerifyCode(String to, String way, String page) {
        try {
            // 查询该邮箱在系统中是否存在 注册时不检测
            if (SystemConstant.FORGOT_VERIFICATION_CODE.equals(way)) {
                RastUser user = userService.getOne(new LambdaQueryWrapper<RastUser>().eq(RastUser::getEmail, to));
                if (ObjectUtil.isEmpty(user)) {
                    throw new ServiceException("The email address does not exist");
                }
            }
            String checkKey = "";
            if (SystemConstant.RESEND_VERIFICATION_CODE.equals(way)) {
                if (StringUtils.isNotBlank(page) && SystemConstant.REGISTER_PAGE.equals(page)) {
                    checkKey = StrUtil.format(RedisConstant.REGISTER_EMAIL, to);
                } else if (StringUtils.isNotBlank(page) && SystemConstant.FORGOT_PAGE.equals(page)) {
                    checkKey = StrUtil.format(RedisConstant.FORGOT_EMAIL, to);
                }
                if (redisService.hasKey(checkKey)) {
                    redisService.delete(checkKey);
                }
            } else {
                checkKey = SystemConstant.FORGOT_VERIFICATION_CODE.equals(way)
                        ? StrUtil.format(RedisConstant.FORGOT_EMAIL, to) : StrUtil.format(RedisConstant.REGISTER_EMAIL, to);
                if (redisService.hasKey(checkKey)) {
                    throw new ServiceException("The verification code has been sent, please check your email");
                }
            }
            // 邮件内容
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject("Reset Password Notification");
            Random random = new Random();
            int code = random.nextInt(9000) + 1000;
            String content = "Please enter the following verification code in the system to reset your password: " + code;
            // 不加参数默认是文本，加上true之后支持html格式文件
            helper.setText(content, true);
            mailSender.send(helper.getMimeMessage());
            redisService.opsForValue().set(checkKey, code, RedisConstant.FORGOT_EMAIL_TIME, TimeUnit.SECONDS);
        } catch (MessagingException e) {
            log.error("发送邮件失败:" + e.getMessage());
        }
    }

    /**
     * 核实验证码是否正确
     *
     * @param email 邮箱
     * @param code  验证码
     * @param way   方法
     */
    public boolean checkingVerifyCode(String email, String code, String way) {
        String key;
        if (SystemConstant.FORGOT_VERIFICATION_CODE.equals(way)) {
            key = StrUtil.format(RedisConstant.FORGOT_EMAIL, email);
        } else {
            key = StrUtil.format(RedisConstant.REGISTER_EMAIL, email);
        }
        Integer verifyCode = (Integer) redisService.opsForValue().get(key);
        if (verifyCode != null) {
            if (StringUtils.equals(code, String.valueOf(verifyCode))) {
                return true;
            }
        } else {
            // 验证码获取错误，请联系管理员
            throw new ServiceException("Verification code acquisition error, please contact the administrator");
        }
        return false;
    }

}
